/*
 * zTree 适配器,添加enableUrl:false[true]选项,用户控制链接点击后动作,true的开启,false为禁用
 * 
 * setting.simbleData.enbale=true setting.async.rootKey,读取树数据是取数据根
 */
(function($) {

	var opts = {
		view : {
			appendNodes : function(setting, level, nodes, parentNode, initFlag,
					openFlag) {
				if (!nodes)
					return [];
				var html = [], childKey = setting.data.key.children;
				for (var i = 0, l = nodes.length; i < l; i++) {
					var node = nodes[i];
					if (initFlag) {
						var tmpPNode = (parentNode) ? parentNode : data
								.getRoot(setting), tmpPChild = tmpPNode[childKey], isFirstNode = ((tmpPChild.length == nodes.length) && (i == 0)), isLastNode = (i == (nodes.length - 1));
						data.initNode(setting, level, node, parentNode,
								isFirstNode, isLastNode, openFlag);
						data.addNodeCache(setting, node);
					}

					var childHtml = [];
					if (node[childKey] && node[childKey].length > 0) {
						// make child html first, because checkType
						childHtml = view.appendNodes(setting, level + 1,
								node[childKey], node, initFlag, openFlag
										&& node.open);
					}
					if (openFlag) {

						view.makeDOMNodeMainBefore(html, setting, node);
						view.makeDOMNodeLine(html, setting, node);
						data.getBeforeA(setting, node, html);
						view.makeDOMNodeNameBefore(html, setting, node);
						data.getInnerBeforeA(setting, node, html);
						view.makeDOMNodeIcon(html, setting, node);
						data.getInnerAfterA(setting, node, html);
						view.makeDOMNodeNameAfter(html, setting, node);
						data.getAfterA(setting, node, html);
						if (node.isParent && node.open) {
							view.makeUlHtml(setting, node, html, childHtml
											.join(''));
						}
						view.makeDOMNodeMainAfter(html, setting, node);
						data.addCreatedNode(setting, node);
					}
				}
				return html;
			},
			asyncNode : function(setting, node, isSilent, callback) {
				var i, l;
				if (node && !node.isParent) {
					tools.apply(callback);
					return false;
				} else if (node && node.isAjaxing) {
					return false;
				} else if (tools.apply(setting.callback.beforeAsync, [
								setting.treeId, node], true) == false) {
					tools.apply(callback);
					return false;
				}
				if (node) {
					node.isAjaxing = true;
					var icoObj = $$(node, consts.id.ICON, setting);
					icoObj.attr({
								"style" : "",
								"class" : consts.className.BUTTON + " "
										+ consts.className.ICO_LOADING
							});
				}

				var tmpParam = {};
				for (i = 0, l = setting.async.autoParam.length; node && i < l; i++) {
					var pKey = setting.async.autoParam[i].split("="), spKey = pKey;
					if (pKey.length > 1) {
						spKey = pKey[1];
						pKey = pKey[0];
					}
					tmpParam[spKey] = node[pKey];
				}
				if (tools.isArray(setting.async.otherParam)) {
					for (i = 0, l = setting.async.otherParam.length; i < l; i += 2) {
						tmpParam[setting.async.otherParam[i]] = setting.async.otherParam[i
								+ 1];
					}
				} else {
					for (var p in setting.async.otherParam) {
						tmpParam[p] = setting.async.otherParam[p];
					}
				}

				var _tmpV = data.getRoot(setting)._ver;
				$.ajax({
							contentType : setting.async.contentType,
							type : setting.async.type,
							url : tools.apply(setting.async.url, [
											setting.treeId, node],
									setting.async.url),
							data : tmpParam,
							dataType : setting.async.dataType,
							success : function(msg) {
								if (_tmpV != data.getRoot(setting)._ver) {
									return;
								}
								var newNodes = [];
								try {
									if (!msg || msg.length == 0) {
										newNodes = [];
									} else if (typeof msg == "string") {
										newNodes = eval("(" + msg + ")");
									} else {
										newNodes = msg;
									}
								} catch (err) {
									newNodes = msg;
								}
								/*--------------rootKey-------------------*/
								if (setting.async.rootKey) {
									newNodes = newNodes[setting.async.rootKey];
								}
								if (node) {
									node.isAjaxing = null;
									node.zAsync = true;
								}
								view.setNodeLineIcos(setting, node);
								if (newNodes && newNodes !== "") {
									newNodes = tools.apply(
											setting.async.dataFilter, [
													setting.treeId, node,
													newNodes], newNodes);
									view.addNodes(setting, node, !!newNodes
													? tools.clone(newNodes)
													: [], !!isSilent);
								} else {
									view
											.addNodes(setting, node, [],
													!!isSilent);
								}
								setting.treeObj.trigger(
										consts.event.ASYNC_SUCCESS, [
												setting.treeId, node, msg]);
								tools.apply(callback);
							},
							error : function(XMLHttpRequest, textStatus,
									errorThrown) {
								if (_tmpV != data.getRoot(setting)._ver) {
									return;
								}
								if (node)
									node.isAjaxing = null;
								view.setNodeLineIcos(setting, node);
								setting.treeObj.trigger(
										consts.event.ASYNC_ERROR, [
												setting.treeId, node,
												XMLHttpRequest, textStatus,
												errorThrown]);
							}
						});
				return true;
			},
			fontCss : function(treeId, treeNode) {
				return (!!treeNode.highlight) ? {
					color : '#A60000',
					'font-weight' : 'bold'
				} : {
					color : '#333',
					'font-weight' : 'normal'
				};
			}
		},
		data : {
			simpleData : {
				enable : true,
				idKey : "id",
				pIdKey : "pid",
				rootPId : null
			}
		},
		async : {
			dataType : "json",
			enable : false,
			rootKey : null
		},
		enableUrl : false,
		debug : true
		// turn on console output (slows down IE8!)
	};

	$.extend(true, $.fn.zTree, {
				_z : {
					data : opts.data,
					async : opts.async,
					view : opts.view
				}
			});
	var zt = $.fn.zTree, tools = zt._z.tools, consts = zt.consts, view = zt._z.view, data = zt._z.data;
	data.exSetting(opts);

	$.fn.menuTree = function(options) {
		/**
		 * start:settings
		 */
		var self = $(this);
		var id = self.attr('id');
		self.attr('autocomplete', 'off');
		var defaults = {
			callback : {
				afterClick : null,
				onClick : onClick
			},
			view : {
				selectedMulti : true
			},
			selectSub : false, //
			target : null,
			keepAll : false,
			menuOnly : false,// 初始化时是否显示菜单
			nodes : [],
			hiddenField : self.attr('hiddenField')
					? self.attr('hiddenField')
					: '_hidden_',
			hiddenValue : self.attr('hiddenValue')
					? self.attr('hiddenValue')
					: '_hiddenValue_',
			validate : false,
			debug : true
			// turn on console output (slows down IE8!)
		};
		var ids = {
			search_id : '_search_' + id,
			clear_id : '_clear_' + id,
			container_id : '_container_' + id,
			tree_id : '_tree_' + id,
			hidden_id : '_hidden_' + id
		}

		var opts = $.extend({}, defaults, options);

		/**
		 * end:settings
		 */
		var container = $('<div></div>').css({
					'display' : 'none',
					'position' : 'absolute',
					'background' : '#ffffff',
					'border' : '1px solid #609bc0'
				}).attr('id', ids.container_id);

		container.append($('<span>搜索:</span>').css({
					'width' : 40,
					'margin-left' : 10,
					'clear' : 'both'
				}));
		container.append($('<input type="text" />').attr('id', ids.search_id));
		container.append($('<button class="button">清空</button>').attr('id',
				ids.clear_id).attr('title', '清空'));

		var treeDom = $('<ul></ul>').addClass('ztree').css({
					'margin-top' : 0,
					'width' : 340
				}).attr('id', ids.tree_id).appendTo(container);

		self.after($('<input type="hidden" />').attr('name', opts.hiddenField)
				.attr('id', ids.hidden_id));
		self.after(container);
		self.css({
					'width' : '120px'
				});
		$('#' + ids.clear_id).click(function() {
					field_hidden.val('');
					self.val('');
				});
		var field_hidden = $('#' + ids.hidden_id);
		var field_search = $('#' + ids.search_id);
		container = $('#' + ids.container_id);
		if (opts.validate) {
			if ($.fn.validate) {
				field_hidden.attr('validate', '{required:true}');
			}
		}
		if (opts.menuOnly) {
			container.css({
						'display' : 'block',
						'background' : 'none',
						'position' : ''
					});
			self.remove();
			$('#' + ids.clear_id).remove();
			hideMenu = function() {
			}
		}
		$('#' + ids.search_id).keyup(function(e) {
			e.preventDefault();
			function update(nodes, highlight) {
				if (nodes) {
					treeObj.expandAll(false);
					for (var i = nodes.length - 1; i >= 0; i--) {
						var node = nodes[i];
						node.highlight = highlight
						// zTree.selectNode(node,highlight);
						treeObj.expandNode(node, highlight, false, false);
						treeObj.expandNode(node.getParentNode(), highlight,
								false, false);
						treeObj.updateNode(node);
					}
				}
			}
			var val = $.trim($(this).val());
			if (val) {
				update(self.data('searchNodes'), false);
				var nodes = treeObj.getNodesByParamFuzzy(
						treeObj.setting.data.key.name, val);
				self.data('searchNodes', nodes);
				update(nodes, true);
			} else {
				update(self.data('searchNodes'), false);
			}
		});

		self.live('click', function(e) {
					var offset = self.offset();
					container.css({
								left : offset.left + "px",
								top : offset.top + self.outerHeight() + "px"
							}).slideDown("fast");

					$("body").bind("mousedown", onBodyDown);
				});

		function onBodyDown(event) {
			if (!(event.target.id == id || event.target.id == ids.container_id || $(event.target)
					.parents('#' + ids.container_id).length > 0)) {
				hideMenu();
			}
		}
		function hideMenu() {
			container.slideUp('fast');
			$('body').unbind('mousedown');
		}
		/**
		 * firebug console output
		 * 
		 * @param text
		 *            String the debug message
		 * @param type
		 *            String the message type [info | warn] (optional)
		 */
		function debug(text, type) {
			if (window.console && window.console.log && opts.debug) {
				if (type == 'info' && window.console.info) {
					window.console.info(text);
				} else if (type == 'warn' && window.console.warn) {
					window.console.warn(text);
				} else {
					window.console.log(text);
				}
			} else {
				alert(text);
			}
		}

		// ------------------ Overwrite zTree
		// ----------------------------------------------------

		function setValue(node) {
			if (node) {
				self.val(node.name);
				field_hidden.val(node.id);
			}
		}
		function onClick(event, treeId, treeNode) {
			if (treeNode) {
				if (treeNode.isParent && opts.selectSub) {
					alert('只能选取子栏目');
				} else {
					setValue(treeNode);
					hideMenu();
				}
				if (opts.target) {
					$('#' + opts.target).trigger('changeTarget',
							[treeId, treeNode]);
				}
			}

			tools.apply(opts.callback.afterClick, [event, treeId, treeNode]);
		};

		/** 父树触发事件响应* */
		self.bind('changeTarget', function(e, treeId, treeNode) {
			while (treeNode.pid != null) {
				treeNode = treeNode.getParentNode();
			}
			var nodes = self.data('nodes');
			var newNodes = [];

			if (!opts.keepAll) {
				var p = parseInt(treeNode.id);
				for (var i = 0; i < nodes.length; i++) {
					var n = nodes[i];
					if (n.id == p) {
						newNodes.push(n);
					}
				}
				treeObj = $.fn.zTree.init(treeDom, opts, newNodes);
			}
			treeObj.expandAll(true);
			var node = treeObj.getNodeByParam('id', treeNode.id);
			if (opts.selectSub && node && node.isParent) {
				var cs = node.children;
				if (cs && cs.length > 0) {
					node = cs[0]
				}
			}
			setValue(node)
			treeObj.selectNode(node);
				// treeObj.addNodes(null,node);
				// debug(node);
			});
		if (opts.ajaxData && opts.ajaxData.enable) {
			$.ajax({
						type : 'post',
						dataType : 'json',
						url : opts.ajaxData.url,
						data : opts.ajaxData.data,
						success : function(data) {
							opts.nodes = data[opts.ajaxData.rootKey]
							treeObj = _initTree(opts.nodes);
							tools
									.apply(opts.callback.onRender, [treeObj,
													data]);
						}
					});
		}
		var interfaces = {
			init : function(nodes, setting) {
				opts = $.extend({}, opts, setting);
				treeObj = _initTree(nodes);
				return treeObj;
			},
			updateSetting : function(setting) {
				return interfaces.init(treeObj.getNodes(), setting);
			},
			expandCheckedNodes : function(flag, flag2) {
				var nodes = treeObj.getCheckedNodes();
				for (var i = nodes.length - 1; i >= 0; i--) {
					treeObj.expandNode(nodes[i], flag, flag2);
				}
			},
			getCheckNodeArray : function() {
				var nodes = treeObj.getCheckedNodes();
				var ids = [];
				for (var i = nodes.length - 1; i >= 0; i--) {
					ids.push(nodes[i].id);
				}
				return ids;
			}
		};

		function _initTree(nodes) {
			var _zTree = $.fn.zTree.init(treeDom, opts, nodes);
			self.data('nodes', _zTree.getNodes());
			var node = _zTree.getNodeByParam('id', opts.hiddenValue);

			if (node && opts.hiddenValue) {
				_zTree.expandNode(node, true, true, false);
				_zTree.selectNode(node);
				setValue(node);
			}
			return $.extend({}, _zTree, interfaces);
		}

		var treeObj = _initTree(opts.nodes);

		return treeObj;
	};
})(jQuery);
